package com.basker.pisces.domain.property.meta;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.springframework.util.CollectionUtils;

import com.basker.pisces.core.meta.IDataField;
import com.basker.pisces.core.meta.IDataObjectMeta;
import com.basker.pisces.core.utils.ConvertUtils;
import com.basker.pisces.domain.property.InvalidPropertyValueException;
import com.basker.pisces.domain.value.ListValue;

/**
 * 列表值对象的属性，这个列表值是只读的
 *
 * @author hangwen
 */
public class ListProperty extends Property<ListValue> {

    @Override
    public void bindField(IDataObjectMeta objectMeta) {
        super.bindField(objectMeta);

        if (this.field instanceof IDataField) {
            Class<?> fieldClass = ((IDataField) this.field).getFieldClass();

            if (!List.class.isAssignableFrom(fieldClass)) {
                throw new RuntimeException("field:'" + this.field.getName() + "' must be a List Class");
            }
        }

        throw new RuntimeException("field:'" + this.field.getName() + "' must be a DataField");
    }

    @SuppressWarnings("unchecked")
    @Override
    public ListValue createValue(Object rawValue) {
        if (rawValue == null) {
            return ListValue.EMPTY;
        }

        if (rawValue instanceof ListValue) {
            return (ListValue) rawValue;
        }

        if (rawValue instanceof String) {
            rawValue = ConvertUtils.convert(rawValue, List.class);
        }

        if (rawValue.getClass().isArray()) {
            rawValue = Arrays.asList((Object[]) rawValue);
        }

        if (rawValue instanceof Collection<?>) {
            Collection<?> coll = (Collection<?>) rawValue;
            if (CollectionUtils.isEmpty(coll)) {
                return ListValue.EMPTY;
            }

            if (coll instanceof List<?>) {
                return new ListValue((List<Object>) coll);
            } else {
                return new ListValue(new ArrayList<>(coll));
            }
        }

        throw new IllegalArgumentException("rawValue:'" + rawValue + "' can not cast to ListValue");
    }

    @Override
    public void setValue(Object dataObject, Object inputValue) throws InvalidPropertyValueException {
        ListValue listValue = this.createValue(inputValue);
        this.setRawValue(dataObject, listValue.getDataValue());
    }

}
